package com.zlcx.tz.live.service.impl;

import com.zlcx.tz.live.constant.PublisherStatus;
import com.zlcx.tz.live.constant.RedisKeyConst;
import com.zlcx.tz.live.domain.LiveRoomPublisherRecord;
import com.zlcx.tz.live.exception.BusinessException;
import com.zlcx.tz.live.exception.CheckParamException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

/**
 * @AUTHOR xhl
 * @CREATE 2019-06-18 15:06
 **/
@Slf4j
@Service
public class FFMPEGService {
    @Autowired
    RedisTemplate redisTemplate;
    @Value("${ffmpeg.path.shell}")
    String shellPath;
    @Resource(name="taskExecutor")
    AsyncTaskExecutor asyncTaskExecutor;
    @Autowired
    LiveRoomPublisherService liveRoomPublisherService;

    @Value("${shangde.recordSecMin}")
    private Long recordSecMin;


    public String  createVideo(Long uid,Long channelId,String imgsPath,String videoAbsolutePath)throws Exception{
        if( uid==null || uid<=0){
            throw new CheckParamException("uid不合法");
        }
        if(channelId==null || channelId<=0){
            throw new CheckParamException("channelId不合法");
        }
        if(StringUtils.isEmpty(imgsPath)){
            throw new CheckParamException("imgsPath不合法");
        }
        if(StringUtils.isEmpty(videoAbsolutePath)){
            throw new CheckParamException("videoAbsolutePath不合法");
        }
        if(!imgsPath.endsWith("/")){
            imgsPath=imgsPath+"/";
        }
        if(!videoAbsolutePath.endsWith("/")){
            videoAbsolutePath=videoAbsolutePath+"/";
        }

        String recordingPicDir = RedisKeyConst.getRecordingPicDirKey(uid,channelId);
        try{
            Process process = Runtime.getRuntime().exec(new String[]{"sh",shellPath,imgsPath,videoAbsolutePath,uid.toString()});
            process.waitFor();
            InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
            BufferedReader reader = new BufferedReader(inputStreamReader);
            String line;
            boolean isSuccess = false;
            while(StringUtils.isNotEmpty(line = reader.readLine())){
                log.info("shell result = "+line);
                if("found".equals(line)){
                    isSuccess = true;
                }
            }
            if(!isSuccess){
                InputStream errorStream = process.getErrorStream();
                String errorInfo = IOUtils.toString(errorStream, Charset.forName("UTF-8"));
                if(errorStream!=null){
                    errorStream.close();
                }
                log.error("视频合成失败，uid={},roomId={},error={}",uid,channelId,errorInfo);
            }

            inputStreamReader.close();
            reader.close();
            log.info("createVideo success .uid={},channelId={}",uid,channelId);
            if(isSuccess){
                redisTemplate.delete(recordingPicDir);
                return uid + ".mp4";
            }else{
                throw new  BusinessException("创造视频失败");
            }
        }catch (Exception e){
            log.error("ffmpeg createVideo  error={}",e);
            throw e;
        }

    }

    public String getRecordVideo( Long roomId,Long userId) throws Exception {

        LiveRoomPublisherRecord publisherRecord = liveRoomPublisherService.getCurrentPublishingRecord( roomId, userId);
        if(publisherRecord==null){
            throw new  BusinessException("上麦记录不存在!");
        }

        if(PublisherStatus.QUIT.getCode()!=publisherRecord.getPublisherState()){
            throw new BusinessException("当前连麦状态无法生成连麦视频");
        }

        Long studySeconds = liveRoomPublisherService.studySeconds(userId, roomId);
        if(studySeconds==null){
            throw new BusinessException("生成连麦视频已经过期");
        }
        if(studySeconds<recordSecMin){
            throw new BusinessException("连麦时间不足"+recordSecMin+"分钟，无法生成连麦视频");
        }

        String userVideoUrlKey = RedisKeyConst.getUserVideoUrlKey(userId,roomId);
        String videoUrl = (String) redisTemplate.opsForValue().get(userVideoUrlKey);
        if(videoUrl==null){
            String createVideoStatusKey = RedisKeyConst.getCreateVideoStatusKey(userId,roomId);
            Integer status = (Integer) redisTemplate.opsForValue().get(createVideoStatusKey);
            if(status==null){
                throw new BusinessException("暂无录制视频");
            }

            Future future = asyncTaskExecutor.submit(new FutureTask(() -> {
                long now = System.currentTimeMillis();
                while (System.currentTimeMillis()-now < 30*1000){
                    String url = (String) redisTemplate.opsForValue().get(userVideoUrlKey);
                    if(StringUtils.isNotBlank(url)){
                        return url;
                    }else{
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                        }
                    }
                }

                return null;
            }));

            while (true){
                if(future.isDone()){
                    Object url = future.get();
                    if(url!=null){
                        videoUrl = String.valueOf(url);
                    }
                    break;
                }
            }
        }

        log.debug("[getRecordVideo] roomId={},userId={},videoUrl={}",roomId,userId,videoUrl);

        return videoUrl;
    }






}
